package com.innovation.chengzhangriji.ui;

import android.Manifest;
import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.provider.Settings;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.Toast;

import com.google.gson.FieldNamingPolicy;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonSyntaxException;
import com.innovation.chengzhangriji.Config;
import com.innovation.chengzhangriji.R;
import com.innovation.chengzhangriji.http.CheckVersionResponse;
import com.innovation.chengzhangriji.http.Client;
import com.innovation.chengzhangriji.preferences.LoginInfo;
import com.innovation.chengzhangriji.ui.event.BaseEvent;
import com.umeng.analytics.MobclickAgent;
import com.innovation.chengzhangriji.ui.dialog.AlertDialog;

import java.lang.reflect.Method;

import de.greenrobot.event.EventBus;
import de.greenrobot.event.Subscribe;
import de.greenrobot.event.ThreadMode;

/**
 * 基类活动
 */
public abstract class BaseActivity extends AppCompatActivity {

    private Toast tipError;

    private NetworkUnavailableListenerImpl mNetworkUnavailableListenerImpl;

    private ProgressDialog progress;

    private ExitBroadcastReceiver receiver;

    private UpdateBroadcastReceiver updateReceiver;

    private MessageBroadcastReceiver messageBroadcastReceiver;

    private AlertDialog logoutDialog;

    protected LoginInfo mLoginInfo;

    protected AlertDialog.OnDialogClickListener logoutDialogListener = new AlertDialog.OnDialogClickListener() {

        @Override
        public void sure() {
            logoutDialog.dismiss();
            Intent intent = new Intent(BaseActivity.this, LoginActivity.class);
            startActivity(intent);
            finish();
        }
    };

    // 当前页面状态 1 前台，0 后台
    protected int state = 1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        logoutDialog = new AlertDialog(this, R.style.Theme_ChZhRJ_Dialog);
        logoutDialog.setOnDialogClickListener(logoutDialogListener);
        tipError = Toast.makeText(this, "", Toast.LENGTH_SHORT);
        mNetworkUnavailableListenerImpl = new NetworkUnavailableListenerImpl();
        mLoginInfo = Config.getLoginInfo(this);

        receiver = new ExitBroadcastReceiver();
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction("cleanLogin");
        registerReceiver(receiver, intentFilter);

        updateReceiver = new UpdateBroadcastReceiver();
        IntentFilter intentFilter1 = new IntentFilter();
        intentFilter1.addAction("UpdateInfo");
        LocalBroadcastManager.getInstance(this).registerReceiver(updateReceiver, intentFilter1);

        // 注册事件通知
        EventBus.getDefault().register(this);

        registerReceiverMessage();
        // 检测权限
        checkPermission();
    }

    protected android.app.AlertDialog checkPermissionDialog = null;

    protected android.app.AlertDialog showConfirm(String title, String message, DialogInterface.OnClickListener okListener) {
        android.app.AlertDialog alertDialog =  new android.app.AlertDialog.Builder(BaseActivity.this)
                .setTitle(title)
                .setMessage(message)
                .setPositiveButton("确定", okListener)
                .setNegativeButton("取消", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        finish();
                    }
                })
                .setCancelable(false)
                .create();
        alertDialog.show();
        return alertDialog;
    }

    /**
     * 显示退出提示
     */
    public void showLogoutDialog() {
        logoutDialog.show("登录已过期，您需要重新登录!");
    }

    @Override
    protected void onResume() {
        super.onResume();
        mLoginInfo = Config.getLoginInfo(this);
        state = 1;
        onPageStart();
        MobclickAgent.onResume(this);
    }

    // 检测权限
    protected void checkPermission() {
        // 检测权限
        if(ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED
                || ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
                || ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED
                || ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) {
            if(!ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_PHONE_STATE)
                    && !ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
                    && !ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)
                    && !ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.RECORD_AUDIO)) {
                // 显示权限请求对话框
                checkPermissionDialog = showConfirm("权限申请", "应用需要申请:" +
                        " 读取手机信息，" +
                        " 存储空间，" +
                        " 打开相机，" +
                        " 录音的权限", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        ActivityCompat.requestPermissions(BaseActivity.this, new String[]{ Manifest.permission.READ_PHONE_STATE,
                                Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO }, Config.REQUEST_ASK_PERMISSIONS);
                    }
                });
            } else {
                ActivityCompat.requestPermissions(BaseActivity.this, new String[]{ Manifest.permission.READ_PHONE_STATE,
                        Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO }, Config.REQUEST_ASK_PERMISSIONS);
            }
        } else {
            permissionGranted();
        }
    }

    // 权限授权后
    protected void permissionGranted() { }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        if(requestCode == Config.REQUEST_ASK_PERMISSIONS) {
            if(grantResults[0] == PackageManager.PERMISSION_GRANTED
                    && grantResults[1] == PackageManager.PERMISSION_GRANTED
                    && grantResults[2] == PackageManager.PERMISSION_GRANTED
                    && grantResults[3] == PackageManager.PERMISSION_GRANTED) {
                if(checkPermissionDialog != null) {
                    checkPermissionDialog.cancel();
                }
                permissionGranted();
            } else {
                // 显示权限请求对话框
                showConfirm("权限申请", "应用需要申请:" +
                        " 读取手机信息，" +
                        " 存储空间，" +
                        " 打开相机，" +
                        " 录音的权限，但已被拒绝，请手动设置", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                        Uri uri = Uri.fromParts("package", getPackageName(), null);
                        intent.setData(uri);
                        startActivity(intent);
                        finish();
                    }
                });
            }
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        onPageEnd();
        MobclickAgent.onPause(this);
    }

    @Override
    protected void onStop() {
        super.onStop();
        state = 0;
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        EventBus.getDefault().unregister(this);
        Client.cancelRequests(this, true);
        unregisterReceiver(receiver);
        LocalBroadcastManager.getInstance(this).unregisterReceiver(updateReceiver);
        unregisterReceiverMessage();
//        ChZhRJApplication.getRefWatcher(this).watch(this);
    }

    /**
     * <h3>页面是直接放在Activity里面的,在此处调用以下方法</h3>
     * <p>MobclickAgent.onPageStart(String);</p>
     */
    protected void onPageStart() {
    }

    /**
     * <h3>页面是直接放在Activity里面的,在此处调用以下方法</h3>
     * <p>MobclickAgent.onPageEnd(String);</p>
     */
    protected void onPageEnd() {
    }

    /**
     * 提示信息
     */
    protected final Toast tipShow(String value) {
        tipError.setText(value);
        tipError.show();
        return tipError;
    }

    /**
     * 提示信息
     */
    protected final Toast tipShow(int resId) {
        tipError.setText(resId);
        tipError.show();
        return tipError;
    }

    /**
     * 网络连接不可用的简单实现
     */
    public final Client.NetworkUnavailableListener networkUnavailableSampleImpl() {
        return mNetworkUnavailableListenerImpl;
    }

    /**
     * 显示未知进度条对话框
     */
    protected final void showProgressDialog(String title, String message) {
        progress = ProgressDialog.show(this, title, message, true);
    }

    /**
     * 消除未知进度条对话框
     */
    protected final void dismissProgressDialog() {
        if (progress != null) {
            progress.dismiss();
        }
    }

    /**
     * 接收到的消息
     * @param type 消息类型 1 日记圈消息
     * @param tag 消息标识 1 新日记 2 新评论 3 赞 4 评论回复
     */
    protected void receiveChZhRJMessage(int type, int tag) {

    }

    /**
     * 把Json格式的字符串转换成实体类型的方法.
     * 注意:实体类中的变量需要用@SerializedName注释
     */
    public final <T> T get(String value, Class<T> classOfT) {
        try {
            Gson gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE).create();
            return gson.fromJson(value, classOfT);
        } catch (JsonSyntaxException exception) {
            Log.d("JsonSyntaxException", exception.getMessage());
        }
        return null;
    }

    private void registerReceiverMessage() {
        IntentFilter filter = new IntentFilter();
        filter.addAction("ChZhRJMessage");
        messageBroadcastReceiver = new MessageBroadcastReceiver();
        LocalBroadcastManager.getInstance(this).registerReceiver(messageBroadcastReceiver, filter);
    }

    private void unregisterReceiverMessage() {
        LocalBroadcastManager.getInstance(this).unregisterReceiver(messageBroadcastReceiver);
    }

    @Subscribe
    public void onEvent(BaseEvent event) {
        if(event.getType() == BaseEvent.TYPE_LOG_STATE_CHANGED) {
            Config.cleanLogin(this);
            mLoginInfo = null;
            if(mLoginInfo == null) {
                if(state == 1) {
                    if(!(this instanceof LoginActivity) && !(this instanceof SettingsActivity)) {
                        showLogoutDialog();
                    } else if(this instanceof  SettingsActivity) {
                        startActivity(new Intent(this, LoginActivity.class));
                        finish();
                    }
                } else {
                    finish();
                }
            }
        }
    }

    private class NetworkUnavailableListenerImpl implements Client.NetworkUnavailableListener {

        @Override
        public void networkUnavailable() {
            dismissProgressDialog();
            tipShow(R.string.tip_network_unavailable);
        }
    }

    private class ExitBroadcastReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (action.equals("cleanLogin")) {
                finish();
            }
        }
    }

    private class UpdateBroadcastReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (action.equals("UpdateInfo")) {
                String updateInfo = intent.getStringExtra("update_info");
                CheckVersionResponse response = get(updateInfo, CheckVersionResponse.class);
                if (response == null) {
                    return;
                }
                if (response.getHasUpdate() == 0) {
                    return;
                }
                Intent intent1 = new Intent(BaseActivity.this, UpdateDialogActivity.class);
                intent1.putExtra("update_info", updateInfo);
                startActivity(intent1);
            }
        }
    }

    private class MessageBroadcastReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            // 1 日记圈消息
            int type = intent.getIntExtra("ChZhRJMessageType", -1);
            // 1 新日记 2 新评论 3 赞 4 评论回复
            int tag = intent.getIntExtra("ChZhRJMessageTag", -1);
            receiveChZhRJMessage(type, tag);
        }
    }
}
